﻿using System;
using System.Diagnostics.Contracts;
using System.Windows;
using Microsoft.Phone.Controls;

namespace DaveSexton.Labs
{
	[ContractClass(typeof(PhoneLabHostPageBaseContract))]
	[CLSCompliant(false)]
	public abstract partial class PhoneLabHostPageBase : PhoneApplicationPage
	{
		#region Public Properties
		#endregion

		#region Private / Protected
		protected abstract PhoneLabController LabController
		{
			get;
		}
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="PhoneLabHostPageBase" /> class for derived classes.
		/// </summary>
		protected PhoneLabHostPageBase()
		{
			Loaded += PhoneLabHostPageBase_Loaded;
		}
		#endregion

		#region Methods
		/// <summary>
		/// When implemented by a derived class, calls <see cref="PhoneLabController.Start()" />.
		/// </summary>
		/// <remarks>
		/// <see cref="PhoneLabController"/> uses <see cref="System.Reflection.Assembly.GetCallingAssembly"/> to locate 
		/// labs, so the host application must be responsible for starting the controller.
		/// </remarks>
		protected abstract void Start();
		#endregion

		#region Event Handlers
		private void PhoneLabHostPageBase_Loaded(object sender, RoutedEventArgs e)
		{
			var controller = LabController;

			Content = (UIElement) controller.Host;

			Start();
		}
		#endregion
	}

	[ContractClassFor(typeof(PhoneLabHostPageBase))]
	internal abstract class PhoneLabHostPageBaseContract : PhoneLabHostPageBase
	{
		protected override PhoneLabController LabController
		{
			get
			{
				Contract.Ensures(Contract.Result<PhoneLabController>() != null);
				return null;
			}
		}
	}
}